﻿using FCSChart.Axis;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Shapes;

namespace FCSChart
{
    [TemplatePart(Name = "Part_XSlider", Type = typeof(Slider))]
    [TemplatePart(Name = "Part_YSlider", Type = typeof(Slider))]
    [TemplatePart(Name = "Part_XThreshold", Type = typeof(Line))]
    [TemplatePart(Name = "Part_YThreshold", Type = typeof(Line))]
    public class ChartInCollecting : ChartWithGraphicals
    {
        static ChartInCollecting()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ChartInCollecting), new FrameworkPropertyMetadata(typeof(ChartInCollecting)));
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            var tempXSlider = GetTemplateChild("Part_XSlider");
            if (tempXSlider != null && tempXSlider is Slider xSlider)
            {
                XSlider = xSlider;
                XSlider.AddHandler(Thumb.DragCompletedEvent, new DragCompletedEventHandler(XSlider_DragCompleted));
            }
            var tempYSlider = GetTemplateChild("Part_YSlider");
            if (tempYSlider != null && tempYSlider is Slider ySlider)
            {
                YSlider = ySlider;
                YSlider.AddHandler(Thumb.DragCompletedEvent, new DragCompletedEventHandler(YSlider_DragCompleted));
            }

            var tempXThreshold = GetTemplateChild("Part_XThreshold");
            if (tempXThreshold != null && tempXThreshold is Line xLine)
            {
                XLine = xLine;
                XLine.MouseMove += XLine_MouseMove;
                XLine.PreviewMouseLeftButtonDown += XLine_PreviewMouseLeftButtonDown;
                XLine.Loaded += (sender, e) =>
                {
                    DrawingXThreshold();
                };
            }
            var tempYThreshold = GetTemplateChild("Part_YThreshold");
            if (tempYThreshold != null && tempYThreshold is Line yLine)
            {
                YLine = yLine;
                YLine.MouseMove += YLine_MouseMove;
                YLine.PreviewMouseLeftButtonDown += YLine_PreviewMouseLeftButtonDown;
                YLine.Loaded += (sender, e) =>
                {
                    DrawingYThreshold();
                };
            }
        }


        #region 增益

        /// <summary>
        /// 增益最小值
        /// </summary>
        public double MinGain
        {
            get { return (double)GetValue(MinGainProperty); }
            set { SetValue(MinGainProperty, value); }
        }
        public static readonly DependencyProperty MinGainProperty = DependencyProperty.Register("MinGain", typeof(double), typeof(ChartInCollecting), new PropertyMetadata(0d));

        /// <summary>
        /// 增益最大值
        /// </summary>
        public double MaxGain
        {
            get { return (double)GetValue(MaxGainProperty); }
            set { SetValue(MaxGainProperty, value); }
        }
        public static readonly DependencyProperty MaxGainProperty = DependencyProperty.Register("MaxGain", typeof(double), typeof(ChartInCollecting), new PropertyMetadata(4096d));

        protected Slider XSlider { get; set; }
        protected Slider YSlider { get; set; }

        /// <summary>
        /// 显示x轴的增益
        /// </summary>
        public bool ShowXGain
        {
            get { return (bool)GetValue(ShowXGainProperty); }
            set { SetValue(ShowXGainProperty, value); }
        }
        public static readonly DependencyProperty ShowXGainProperty = DependencyProperty.Register("ShowXGain", typeof(bool), typeof(ChartInCollecting), new PropertyMetadata(false));
        /// <summary>
        /// 显示y轴的增益
        /// </summary>
        public bool ShowYGain
        {
            get { return (bool)GetValue(ShowYGainProperty); }
            set { SetValue(ShowYGainProperty, value); }
        }
        public static readonly DependencyProperty ShowYGainProperty = DependencyProperty.Register("ShowYGain", typeof(bool), typeof(ChartInCollecting), new PropertyMetadata(false));

        /// <summary>
        /// x轴增益值
        /// </summary>
        public double XGainValue
        {
            get { return (double)GetValue(XGainValueProperty); }
            set { SetValue(XGainValueProperty, value); }
        }
        public static readonly DependencyProperty XGainValueProperty = DependencyProperty.Register("XGainValue", typeof(double), typeof(ChartInCollecting), new PropertyMetadata(1000d));
        /// <summary>
        /// y轴增益值
        /// </summary>
        public double YGainValue
        {
            get { return (double)GetValue(YGainValueProperty); }
            set { SetValue(YGainValueProperty, value); }
        }
        public static readonly DependencyProperty YGainValueProperty = DependencyProperty.Register("YGainValue", typeof(double), typeof(ChartInCollecting), new PropertyMetadata(1000d));

        /// <summary>
        /// x轴增益发生变化
        /// </summary>
        public ICommand XGainChangedCommand
        {
            get { return (ICommand)GetValue(XGainChangedCommandProperty); }
            set { SetValue(XGainChangedCommandProperty, value); }
        }
        public static readonly DependencyProperty XGainChangedCommandProperty = DependencyProperty.Register("XGainChangedCommand", typeof(ICommand), typeof(ChartInCollecting), new PropertyMetadata(null));

        /// <summary>
        /// y轴增益发生变化
        /// </summary>
        public ICommand YGainChangedCommand
        {
            get { return (ICommand)GetValue(YGainChangedCommandProperty); }
            set { SetValue(YGainChangedCommandProperty, value); }
        }
        public static readonly DependencyProperty YGainChangedCommandProperty = DependencyProperty.Register("YGainChangedCommand", typeof(ICommand), typeof(ChartInCollecting), new PropertyMetadata(null));

        private void XSlider_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            XGainChangedCommand?.Execute(this.XGainValue);
        }
        private void YSlider_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            YGainChangedCommand?.Execute(this.YGainValue);
        }
        #endregion

        #region 阈值
        protected Line XLine { get; set; }
        protected Line YLine { get; set; }

        /// <summary>
        /// 显示x轴阈值
        /// </summary>
        public bool ShowXThreshold
        {
            get { return (bool)GetValue(ShowXThresholdProperty); }
            set { SetValue(ShowXThresholdProperty, value); }
        }
        public static readonly DependencyProperty ShowXThresholdProperty = DependencyProperty.Register("ShowXThreshold", typeof(bool), typeof(ChartInCollecting), new PropertyMetadata(false));

        /// <summary>
        /// 显示y轴阈值
        /// </summary>
        public bool ShowYThreshold
        {
            get { return (bool)GetValue(ShowYThresholdProperty); }
            set { SetValue(ShowYThresholdProperty, value); }
        }
        public static readonly DependencyProperty ShowYThresholdProperty = DependencyProperty.Register("ShowYThreshold", typeof(bool), typeof(ChartInCollecting), new PropertyMetadata(false));

        /// <summary>
        /// x轴阈值
        /// </summary>
        public double XThresholdValue
        {
            get { return (double)GetValue(XThresholdValueProperty); }
            set { SetValue(XThresholdValueProperty, value); }
        }
        public static readonly DependencyProperty XThresholdValueProperty = DependencyProperty.Register("XThresholdValue", typeof(double), typeof(ChartInCollecting), new PropertyMetadata(5000d, (sender, e) =>
        {
            if (sender is ChartInCollecting chart) chart.DrawingXThreshold();
        }));

        /// <summary>
        /// y轴阈值
        /// </summary>
        public double YThresholdValue
        {
            get { return (double)GetValue(YThresholdValueProperty); }
            set { SetValue(YThresholdValueProperty, value); }
        }
        public static readonly DependencyProperty YThresholdValueProperty = DependencyProperty.Register("YThresholdValue", typeof(double), typeof(ChartInCollecting), new PropertyMetadata(5000d, (sender, e) =>
        {
            if (sender is ChartInCollecting chart) chart.DrawingYThreshold();
        }));

        /// <summary>
        /// x轴上的阈值发生变化命令
        /// </summary>
        public ICommand XThresholdChangedCommand
        {
            get { return (ICommand)GetValue(XThresholdChangedCommandProperty); }
            set { SetValue(XThresholdChangedCommandProperty, value); }
        }
        public static readonly DependencyProperty XThresholdChangedCommandProperty = DependencyProperty.Register("XThresholdChangedCommand", typeof(ICommand), typeof(ChartInCollecting), new PropertyMetadata(null));

        /// <summary>
        /// y轴上的阈值发生变化命令
        /// </summary>
        public ICommand YThresholdChangedCommand
        {
            get { return (ICommand)GetValue(YThresholdChangedCommandProperty); }
            set { SetValue(YThresholdChangedCommandProperty, value); }
        }
        public static readonly DependencyProperty YThresholdChangedCommandProperty = DependencyProperty.Register("YThresholdChangedCommand", typeof(ICommand), typeof(ChartInCollecting), new PropertyMetadata(null));




        bool isMoveXLine = false;
        bool isMoveYLine = false;
        private void XLine_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            isMoveXLine = true;
        }

        private void YLine_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            isMoveYLine = true;
        }
        private void XLine_MouseMove(object sender, MouseEventArgs e)
        {
            if (isMoveXLine && XAxis != null && ViewPanel != null)
            {
                var point = e.GetPosition(ViewPanel);
                XThresholdValue = XAxis.GetLocationValue(point.X);
                e.Handled = true;
            }
        }

        private void YLine_MouseMove(object sender, MouseEventArgs e)
        {
            if (isMoveYLine && YAxis != null && ViewPanel != null)
            {
                var point = e.GetPosition(ViewPanel);
                YThresholdValue = YAxis.GetLocationValue(point.Y);
                e.Handled = true;
            }
        }
        protected override void Panel_MouseMove(object sender, MouseEventArgs e)
        {
            if (isMoveXLine)
            {
                var point = e.GetPosition(ViewPanel);
                XThresholdValue = XAxis.GetLocationValue(point.X);
                e.Handled = true;
            }
            else if (isMoveYLine)
            {
                var point = e.GetPosition(ViewPanel);
                YThresholdValue = YAxis.GetLocationValue(point.Y);
                e.Handled = true;
            }
            else base.Panel_MouseMove(sender, e);
        }

        protected override void Panel_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {

            if (isMoveXLine)
            {
                isMoveXLine = false;
                XThresholdChangedCommand?.Execute(XThresholdValue);
            }
            else if (isMoveYLine)
            {
                isMoveYLine = false;
                YThresholdChangedCommand?.Execute(YThresholdValue);
            }
            else base.Panel_MouseLeftButtonUp(sender, e);
        }

        protected void DrawingXThreshold()
        {
            if (XAxis != null && XLine != null && !double.IsNaN(XThresholdValue) && !double.IsInfinity(XThresholdValue))
            {
                XLine.X1 = XAxis.GetValueLocation(XThresholdValue);
            }
        }

        protected void DrawingYThreshold()
        {
            if (YAxis != null && YLine != null && !double.IsNaN(YThresholdValue) && !double.IsInfinity(YThresholdValue))
            {
                YLine.Y1 = YAxis.GetValueLocation(YThresholdValue);
            }
        }
        #endregion
        protected override void DrawingGraphicals()
        {
            base.DrawingGraphicals();
            DrawingXThreshold();
            DrawingYThreshold();
        }
    }
}
